/**
 * JAVACC DEMO 1.0
 */
package com.apache.uct.common.filter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Properties;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.apache.api.vo.ResultMsg;
import com.apache.client.AesClientUtil;
import com.apache.client.IBaseReplaceCard;
import com.apache.client.UctCoreClient;
import com.apache.license.validator.OsUtils;
import com.apache.oscache.OsCacheManager;
import com.apache.passport.common.PassportHelper;
import com.apache.tools.DateUtils;
import com.apache.tools.StrUtil;
import com.apache.uct.common.LoginUser;
import com.apache.uct.common.PBOSSOTools;
import com.apache.uct.common.entity.Role;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.apache.api.vo.ResultEntity;
import com.apache.cache.util.Validator;
import com.apache.license.filter.AbstractFilter;
import com.apache.license.validator.LicenseValidate;
import com.apache.rpc.common.JsonEntityParese;
import com.apache.security.util.SecurityHttpServletRequest;
import com.apache.security.util.SecurityHttpServletResponse;
import com.apache.uct.common.ToolsUtil;

import net.sf.json.JSONObject;

/**
 * description:  系统license验证类
 *
 * @author Hou Dayu 创建时间：2016-12-23
 */
public class LicenseFilter extends AbstractFilter {

	private Logger log = LoggerFactory.getLogger(getClass());
	private String propertiesPath;
	private Properties prop;
	private String authorizationCode;
	/**
	 * TODO 简单描述该方法的实现功能（可选）.
	 */
	public void destroy() {
		///
	}

	/**
	 * TODO 简单描述该方法的实现功能（可选）.
	 */
	public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain arg2)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) srequest;
		HttpServletResponse response = (HttpServletResponse) sresponse;
		String path = request.getRequestURI();
		if (path.indexOf("/images/") !=-1 || path.indexOf("/js/") !=-1 || path.indexOf("/common/") !=-1 || path.indexOf("/template/") !=-1 ) {
			arg2.doFilter(request, response);
			return ;
		}
		boolean authFlag = AuthRequestSecurity();
		if(!authFlag){
			response.setStatus(500);
			this.outputJson(JSONObject.fromObject(new ResultMsg("F", "Invalid trial version authorization code")).toString(), response, request.getParameter("callback"));
			return ;
		}
		log.debug("sessionId="+request.getSession().getId());
		int s = path.indexOf("/doService");
		if (s >= 0) {
			if (!LicenseValidate.getInstance().isEffective()) {//license验证不通过
				ResultEntity entity = new ResultEntity();
				entity.setResult("false");
				entity.setMessage("功能已停用或已删除！");
				String callback = request.getParameter("callback");
				if (Validator.isNull(callback)) {
					response.setContentType("text/html; charset=UTF-8");
					PrintWriter out = response.getWriter();
					out.print(JsonEntityParese.instance().toXml(entity));
					out.flush();
				} else {///支持jsonp数据格式
					PrintWriter out = response.getWriter();
					response.setContentType("application/javascript");
					JSONObject json = JSONObject.fromObject(entity);
					out.print(callback + "(" + json.toString() + ")");
					out.flush();
				}
				return;
			}
		} else {
			String cookieValue = PassportHelper.getInstance().getCurrCookie(request);
			if(StrUtil.isNull(cookieValue)){
				cookieValue = request.getHeader("zuultokenid");
				String pkt = request.getParameter("tokenId");
				if ("undefined".equalsIgnoreCase(pkt))
					pkt = "";
				cookieValue = StrUtil.doNull(cookieValue,pkt);
			}
			if(StrUtil.isNotNull(cookieValue)){
//				String value = StrUtil.doNull(PassportHelper.getInstance().getCurrCookie(request, "_uc.sso"),request.getHeader("zuulucsso"));
				LoginUser loginUser = OsCacheManager.getInstance().getLoginUser(cookieValue); //(LoginUser) request.getSession().getAttribute("loginUser");
				if (null == loginUser) {
//					if (!cookieValue.startsWith("uni_") && ToolsUtil.isNull(value)) {
//						response.sendRedirect(request.getContextPath() + path);
//						return;
//					}
					loginUser = UctCoreClient.getLoginUserFromUserCenterSso("", cookieValue);
					OsCacheManager.getInstance().putLoginUser(cookieValue, loginUser);
				}
				if (!ToolsUtil.isEmpty(loginUser)) {
					request.getSession().setAttribute("loginUser", loginUser);//获取session中信息
					if ("T".equals(ToolsUtil.getInstance().getValueByKey("local_user"))) {//用户换证处理操作
						String reflectPath = ToolsUtil.getInstance().getValueByKey("reflect_path");
						try {
							if (StrUtil.isNotNull(reflectPath)) {
								Class<?> clazz = Class.forName(reflectPath);
								IBaseReplaceCard replaceCard = (IBaseReplaceCard) clazz.newInstance();
								boolean flag = replaceCard.replaceCard(loginUser, request, response);//数据插入到本地，并且换证
								if (!flag) {
									response.sendRedirect(request.getContextPath() + "/");
									return;
								}
							}
						} catch (Exception e) {
							log.error("换证失败", e);
						}
					}
					Object objRoles = OsCacheManager.getInstance().getCustomerUser(loginUser.getUser().getUserId());
					if (ToolsUtil.isEmpty(objRoles)) {
						List<Role> roles = PBOSSOTools.getRolesForLoginUser(request);//获取用户角色列表
						if (!ToolsUtil.isEmpty(roles)) {
							request.getSession().setAttribute("loginUserRoles", roles);
							OsCacheManager.getInstance().putCustomerUser(loginUser.getUser().getUserId(),roles);
						}
					} else {
						request.getSession().setAttribute("loginUserRoles", objRoles);
					}
				}
			}
		}
		if ("true".equalsIgnoreCase(ToolsUtil.getInstance().getValueByKey("is_open_security_filter"))) {//是否开启安全过滤
			arg2.doFilter(new SecurityHttpServletRequest(request), new SecurityHttpServletResponse(response));
		} else {
			arg2.doFilter(request, response);
		}
	}

	/**
	 * TODO 简单描述该方法的实现功能（可选）.
	 */
	public void init(FilterConfig arg0) throws ServletException {
		this.initLincense();
		propertiesPath = Validator.getClassLoaderPath();
		prop = Validator.getProperties(propertiesPath,"cache-conf.properties");
		String authCode = prop.getProperty("cache_authorization_code");
		if(StrUtil.isNotNull(authCode)){
			JSONObject acjson = JSONObject.fromObject(AesClientUtil.getInstance().decryptEcbMode(authCode));
			if("0".equals(acjson.getString("infoType"))){
				prop.setProperty("cache_authorization_code","");
			}
		}
		Properties appProp = Validator.getProperties(propertiesPath,"application.properties");
		authorizationCode = appProp.getProperty("spring.authorization.code");
	}

	private boolean AuthRequestSecurity() {
		String checkStr = getProperty("cache_authorization_code");
		boolean checkFlag = true;
		long ntime = DateUtils.strToLong(DateUtils.Now.fmt_yyyyMMdd_HH(),DateUtils.FmtStr.yyyyMMdd_HH);
		JSONObject authJson = null;
		try {
			String ip = OsUtils.getLocalIp();
			if (StrUtil.isNull(checkStr) && StrUtil.isNull(authorizationCode)) {
				authJson = new JSONObject();
				authJson.put("infoType", "0");
				authJson.put("startTime", ntime);
				authJson.put("flag", "");
				String devStr = AesClientUtil.getInstance().encryptEcbMode(authJson.toString());
				setProperty(devStr);
			} else if (StrUtil.isNull(checkStr) && StrUtil.isNotNull(authorizationCode)) {
				boolean ifAuthFlag = isAuthCode(ntime, ip, authorizationCode);
				if (ifAuthFlag) {
					authJson = new JSONObject();
					authJson.put("infoType", "0");
					authJson.put("startTime", ntime);
					authJson.put("flag", "");
					String devStr = AesClientUtil.getInstance().encryptEcbMode(authJson.toString());
					setProperty(devStr);
				}
			} else {
				String strJson = AesClientUtil.getInstance().decryptEcbMode(checkStr);
				authJson = JSONObject.fromObject(strJson);
				String ipflag = authJson.getString("flag");
				boolean ifDev = "0".equals(authJson.getString("infoType"));
				if (ifDev || !ip.equals(ipflag)) {
					boolean testFlag = true;
					if (StrUtil.isNotNull(authorizationCode)) {
						testFlag = isAuthCode(ntime, ip, authorizationCode);
					}
					if (testFlag) {
						long ptime = authJson.getLong("startTime");
						if ((ntime - ptime) / 3600000 > 48 || !ifDev) {
							checkFlag = false;
						}
					}
				}
			}
		} catch (Exception e){
			checkFlag = false;
		}
		return checkFlag;
	}

	private boolean isAuthCode(long ntime, String ip, String authorizationCode){
		boolean testFlag = true;
		String acJsonStr = AesClientUtil.getInstance().decryptEcbMode(authorizationCode);
		JSONObject acjson = JSONObject.fromObject(acJsonStr);
		long stime = DateUtils.strToLong(acjson.getString("startTime"), DateUtils.FmtStr.yyyyMMdd_HH);
		int effectiveTime = acjson.getInt("effectiveTime");
		if((ntime-stime)/3600000 <= effectiveTime){
			acjson.put("infoType", "1");
			acjson.put("flag", ip);
			String devStr = AesClientUtil.getInstance().encryptEcbMode(acjson.toString());
			setProperty(devStr);
			testFlag = false;
		}
		return testFlag;
	}

	/**
	 * 输出json数据
	 */
	private void outputJson(String json, HttpServletResponse response, String callback)
			throws IOException {
		if (StrUtil.isNotNull(json)) {
			PrintWriter out = response.getWriter();
			if (StrUtil.isNull(callback)) {
				response.setContentType("text/html;charset=UTF-8");
				response.setHeader("Access-Control-Allow-Origin", "*");
				response.setHeader("Access-Control-Allow-Methods", "POST,GET");
				response.setHeader("Access-Control-Allow-Credentials", "true");
				out.print(json);
			} else {
				response.setContentType("application/javascript");
				out.print(callback + "(" + json + ")");
			}
			out.flush();
			out.close();
		}
	}

	/**
	 * @Title: setProperty
	 * @Description: 保存key-value到配置文件中
	 */
	private void setProperty(String value) {
		try {
			if(prop != null) {
				prop.setProperty("cache_authorization_code", value);
				prop.store(new FileOutputStream(new File(propertiesPath+"cache-conf.properties")), "utf-8");
			}
		} catch(Exception ex) {
		}
	}

	private String getProperty(String key) {
		if(prop != null) {
			return prop.getProperty(key);
		}
		return "";
	}
}
